(function(){
	var http = require('http'); 
	require('./Global.js');
	
	namespace('org.jsmud');
	
	var services = {};
	
	org.jsmud.ServiceManager = function(){
	};
	org.jsmud.ServiceManager.prototype = {
		get : function(name){
			return services[name];
		},
		set : function(name, service){
			services[name] = service;
		},
		_describe : function(name){
			var service = services[name];
			if( !service ){
				return {error:_('Service \'${name}\' does not exist.', {name:name})};
			}
			var endpoints = {};
			for(member in service){
				if( typeof service[member] === 'function' && !member.match(/^_.*/) )
					endpoints[member] = {
						__serviceName:name
						,__methodName:member
					};
			}
			return endpoints;
		},	
        createEndpoint : function(name, key, value){
        	var input = {name:name, method:key, value:value};
        	var serviceManager = this;
        	return (function(){
        		var options = {
            		host  : 'localhost'
            		,port : 8080
            		,path : _('/invoker/${name}/${method}', input)
            		,method : 'POST'
            	};
        		var _arguments = arguments;
        		var _scope = this;
        		var _result = {
        			_isReady : false,
    				on : function(event, callback){
        				this[event] = callback;
        				if(event === 'ready' && this._isReady){
        					callback();
        				}
        			}	
        		};
        		var req = http.request(options, function(res){
        			var body = '';
        			res.on('data', function(data){
        				body += data.toString();
        			});
        			res.on('end', function(){
        				var obj = JSON.parse(body);
        				//console.log(obj);
        				iterate(obj.args, function(_value, index){
        					if(_value && _value.__alternate){;
        						obj.args[index] = serviceManager.getService(_value.__alternate);
        					}
        				});
        				if(obj.index === undefined){
        					obj = obj.result;
        					if(obj && obj.__alternate ){
        						serviceManager.getService(obj.__alternate, function(svc){
        							//console.log(svc);
        							for(member in svc)
        								_result[member] = svc[member];
        							_result._isReady = true;
                					if(_result.ready){
                						_result.ready();
                					}
        						});
        					}else if(obj){
        						for(member in obj)
        							_result[member] = obj[member];
        						_result._isReady = true;
            					if(_result.ready){
            						_result.ready();
            					}
        					}else{
        						_result._isReady = true;
            					if(_result.ready){
            						_result.ready();
            					}
        					}
        				}else{
        					_arguments[obj.index].apply(_scope, obj.args);
        				}
        			});
        		});
        		var args = [];
        		iterate(arguments, function(value, index){
        			if( typeof value === 'function' )
        				args.push('__function');
        			else
        				args.push(value);
        		});
        		var data = JSON.stringify(args);
        		req.setHeader('content-type', 'application/json');
        		req.setHeader('content-length', data.length);
        		//console.log(data);
        		req.end(data);
        		return _result;
        	});
        },
        getService : function(name, callback){
        	if(services[name]){
        		if( callback )
        			callback(services[name]);
        		return services[name];
        	}else{
        		console.log("Building Service : " + name);
        	}
        	var serviceManager = this;
        	var options = {
        		host  : 'localhost'
        		,port : 8080
        		,path : '/invoker/' + name + '/_describe'
        	}
        	var service = {
    			name : name	
    			,_isReady : false
    			,on : function(event, callback){
    				this[event] = callback;
    				if(event === 'ready' && this._isReady){
    					callback();
    				}
    			}
    		};
        	var req = http.request(options, function(response){
        		//console.log("Responded");
        		var body = '';
        		response.on('data', function(data){
        			body += data.toString();
        		});
        		response.on('end', function(){
        			//console.log(body);
        			var obj = JSON.parse(body);
        			iterate(obj, function(value, key){
        				service[key] = serviceManager.createEndpoint(name, key, value);
        			});
        			services[name] = service;
        			callback(service);
        			service._isReady = true;
        			if( service.ready ){
        				service.ready();
        			}
        		});
        	});
        	req.end();
        	return service;
        }
	}
	if( module ){
		module.exports = new org.jsmud.ServiceManager();
	}
})()